package com.wnxy.admin.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wnxy.admin.common.handler.Asserts;
import com.wnxy.admin.common.handler.BusinessEnum;
import com.wnxy.admin.dto.PageResult;
import com.wnxy.admin.dto.RuleQueryDto;
import com.wnxy.admin.entity.ChargingRules;
import com.wnxy.admin.mapper.ChargingRulesMapper;
import com.wnxy.admin.service.IChargingRulesService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author All
 * @since 2023-11-29
 */
@Service
public class ChargingRulesServiceImpl extends ServiceImpl<ChargingRulesMapper, ChargingRules> implements IChargingRulesService {

    private final ChargingRulesMapper chargingRulesMapper;

    public ChargingRulesServiceImpl(ChargingRulesMapper chargingRulesMapper) {
        this.chargingRulesMapper = chargingRulesMapper;
    }

    @Override
    @Transactional
    public void editRules(ChargingRules chargingRules) {
        // 判断规则id, id等于1的规则无法禁用(常规收费)
        Asserts.fail(chargingRules.getRuleId() == 1 && chargingRules.getStatus() == 0,
                BusinessEnum.RULES_CANNOT_BE_DISABLED);

        //时段单价小于等于0时, 自动将时段单价设置为1.00
        if(chargingRules.getUnitPrice().compareTo(BigDecimal.ZERO) <= 0) {
            chargingRules.setUnitPrice(new BigDecimal("1.00"));
        }
        chargingRulesMapper.updateById(chargingRules);
    }

    @Override
    @Transactional
    public void removeRules(List<Long> ruleIds) {

        if (CollectionUtils.isEmpty(ruleIds)) {
            return; // 如果规则 ID 列表为空，直接返回
        }
        List<ChargingRules> enabledRules  = chargingRulesMapper.selectBatchIds(ruleIds);

        for (ChargingRules rule : enabledRules) {
            if (rule.getStatus() == 1) {
                // 1001 当前规则已启用 (抛出异常)
                Asserts.fail(true, BusinessEnum.RULE_IS_OCCUPIED);
            }
            rule.setFlag(rule.getRuleId().intValue());
            chargingRulesMapper.updateById(rule);
        }
    }

    @Override
    public PageResult queryRules(RuleQueryDto ruleQueryDto) {
        Page page = Page.of(ruleQueryDto.getPageNum(), ruleQueryDto.getPageSize());

        //根据规则名称/时段单价 进行匹配
        Page result = chargingRulesMapper.selectPage(page, Wrappers.lambdaQuery(ChargingRules.class)
                .like(!StringUtils.isEmpty(ruleQueryDto.getChargingName()), ChargingRules::getChargingName, ruleQueryDto.getChargingName())
                .like(ruleQueryDto.getUnitPrice() != null, ChargingRules::getUnitPrice, ruleQueryDto.getUnitPrice())
                .eq(ChargingRules::getFlag, 0));


        return new PageResult<>(result.getTotal(), result.getRecords());
    }

    /**
     * 根据规则的 ID 获取规则对象列表。
     *
     * @param rules 以逗号分隔的规则 ID 字符串
     * @return 规则对象列表，如果规则为空，则返回空列表
     */
    @Override
    public List<ChargingRules> getRules(String rules) {
        List<ChargingRules> chargingRulesList = new ArrayList<>();

        if (rules.isEmpty()) {
            return new ArrayList<>();
        }

        // 以逗号分割字符串  \\s*,\\s*表示匹配逗号前后可带有任意数量的空白字符
        String[] ruleIds = rules.split("\\s*,\\s*");

        // 使用 Stream API 将字符串数组转为规则对象列表
        chargingRulesList = Arrays.stream(ruleIds)
                .mapToLong(Long::parseLong)
                .mapToObj(this::getChargingRuleById)
                .filter(rule -> rule != null)
                .collect(Collectors.toList());

        return chargingRulesList;
    }

    /**
     * @param ruleId 规则 ID
     * @return 规则对象，如果不存在则返回 null
     */
    private ChargingRules getChargingRuleById(long ruleId) {
        try {
            return chargingRulesMapper.selectById(ruleId);
        } catch (NumberFormatException e) {
            // 记录日志或其他错误处理逻辑 TODO
            return null;
        }
    }
}
